package pixel;

// DeStegano.java; fuer Giessen, 2.7.2009
// baut auf auf Stegano.java; INFO13, 27.9.2006
/*
 * Auslesen des Textes aus dem Bild stegano.png
 * Es wird jeweils das LSB des ARGB-Wertes jedes Pixels
 * genommen; je 8 werden zu einem Zeichen zusammengesetzt und
 * herausgeschrieben.
 * (Dies wird fuer das gesamte Bild gemacht -- unabhängig
 *  davon, ob überhaupt eine Botschaft darin versteckt ist!)
 */

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.io.*;

public class DeStegano extends JApplet{
  private String inFileName="stegano.png";
  private boolean istKnopfGedrueckt;
  private boolean istZeigen;
  private BufferedImage dasSteganoBild=null;
  private JButton btnStart;
  private JButton btnZeigen;
  private JScrollPane spAusgabe;
  private JTextArea taAusgabe;

  private void erzeugeKomponenten() {
    btnStart=new JButton("Bild laden ("+inFileName+")");
    btnZeigen=new JButton("Text zeigen");
    taAusgabe=new JTextArea("");
    spAusgabe=new JScrollPane(taAusgabe);
  }

  private void registriereZuhoerer() {
    btnStart.addActionListener(new BL());
    btnZeigen.addActionListener(new BLZeigen());
  }

  private void baueLayout(){
    Container cp=getContentPane();
    cp.setLayout(new BorderLayout());
    // NORTH
    JPanel pN=new JPanel(new FlowLayout(FlowLayout.RIGHT));
    pN.add(btnZeigen);
    pN.add(btnStart);
    cp.add(pN, BorderLayout.NORTH);
    // CENTER
    cp.add(spAusgabe, BorderLayout.CENTER);
  }

  @Override
  public void init(){
    erzeugeKomponenten();
    registriereZuhoerer();
    baueLayout();
    // zur Sicherheit:
    istKnopfGedrueckt=false;
  }

  public class BL implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e){
      try{
        dasSteganoBild=ImageIO.read(new File(inFileName));
      } catch(IOException ioe){
        System.err.println("Fehler beim Lesen von "+inFileName+": ");
        System.err.println(ioe);
        System.exit(2);
      }
      istKnopfGedrueckt=true;
    }
  }

  public class BLZeigen implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e){
      if(istKnopfGedrueckt){
        istZeigen=true;
        taAusgabe.append("\nnur der erste Teil wird gueltig sein,\n");
        taAusgabe.append("\nText wird gesucht ... \n");
        taAusgabe.append("==========\n");
        zeigeText(dasSteganoBild);
      } else taAusgabe.append("\n     erst das Bild laden!\n");
    }
  }

  private int setzeBit(int inInteger, int anPos){
    return inInteger | (1 << anPos);
  }

  private int loescheBit(int inInteger, int anPos){
    return ~((~inInteger) | (1 << anPos));
  }

  private boolean istBitgesetzt(int inInteger, int anPos){
    return ((inInteger >>> anPos) & 1) == 1;
  }

  private void zeigeText(BufferedImage einBild){
    String sAusgabe="";
    int rgbWert;
    int breite=einBild.getWidth();
    int hoehe =einBild.getHeight();
    int bitInBuchstabe=7;
    int iChar=0;
    int spaltenZaehler=0;
    for(int y=0; y<hoehe; y++){
      for(int x=0; x<breite; x++){
        rgbWert=einBild.getRGB(x, y);
        if(istBitgesetzt(rgbWert, 0))
          iChar=setzeBit(iChar, bitInBuchstabe);
        bitInBuchstabe--;
        if(bitInBuchstabe<0){
          bitInBuchstabe=7;
          sAusgabe=sAusgabe+(char)iChar;
          iChar=0;
          spaltenZaehler++;
          if((spaltenZaehler % 60)==0)
            sAusgabe=sAusgabe+"\n";
        }
      }
    }
    taAusgabe.append(sAusgabe);
  }

  public static void main(String[] args) {
    DeStegano meinAppchen=new DeStegano();
    JFrame meinFrame=new JFrame("DeStegano");
    meinFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    meinFrame.getContentPane().add(meinAppchen, BorderLayout.CENTER);
    meinAppchen.init();
    meinAppchen.start();
    meinFrame.setSize(600, 500);
    meinFrame.setVisible(true);
  }

  private String gibBin(int iZahl, int stellen){
    long lZahl=iZahl;
    if(iZahl<0)
      lZahl=-lZahl-1;
    String sErg=gibBinaerRek(lZahl);
    while(sErg.length()<stellen)
      sErg="0"+sErg;
    if (iZahl<0){
      sErg=sErg.replace('0', 'x');
      sErg=sErg.replace('1', '0');
      sErg=sErg.replace('x', '1');
    }
    return sErg;
  }

  private String gibBinaerRek(long iZahl) {
    if (iZahl<2) return ""+iZahl;
    else return gibBinaerRek(iZahl/2)+(iZahl%2);
  }
}
